home *** CD-ROM | disk | FTP | other *** search
/ Disc to the Future 2 / Disc to the Future Part II Programmer's Reference (Wayzata Technology)(6013)(1992).bin / MAC / THINKC / 3_0 / OIC_1 / EXPLORER.S_K < prev    next >
Text File  |  1989-03-07  |  42KB  |  991 lines

  1.                            O.I.C  Objects-in-C  (V1.02)
  2.                            ===================
  3.                        
  4.                        Explorer's Kit Documentation
  5.                     
  6.                     Copyright ⌐ John Wainwright, 1988, 1989
  7.                     
  8.                          454 West 20th Street, #2
  9.                          New York, NY  10011
  10.                          
  11.                          Compuserve : 72657,2534
  12.                          
  13.                           All rights reserved
  14.                        
  15.                           Shareware fee : $20
  16.                        
  17.          This is the shareware, explorer's release of a portable
  18.          object-oriented programming environment for the C pro-
  19.          gramming language.  The kit contains the complete objects
  20.          environment, a bunch of simple, but useful demo classes
  21.          and this, EXPERTS ONLY, documentation - enough for ex-
  22.          perienced C programmers that know something about object-
  23.          oriented techniques to take advantage of them in the
  24.          excellent C environments now on the Mac.
  25.          
  26.          It is supplied as a verion 3, LightSpeed C project but
  27.          the source files are simple text files that should be
  28.          readable by any of the Macintosh C compilers.
  29.          
  30.          The full release will come with complete documentation 
  31.          and an EXTENSIVE set of classes for developing Mac
  32.          applications - a persistent object store, a complete
  33.          Model-View-Controller system for accessing the Mac
  34.          toolbox, 2D & 3D PHIGGS-like imaging spaces integrated
  35.          with the MVC system, a polymorhpic, object-oriented
  36.          spreadsheet system, and an embeddable Common Lisp
  37.          subset interpreter with OIC interface.
  38.          
  39.          Acknowledgements:  Tim Long and Andrew Nicholson
  40.                              both contributed materially to
  41.                              the ideas in this system.
  42.                              
  43.                              
  44.     ** corresponds to version V1.02 released on Mar 5th, 1989   **
  45.     **        the V1.01 changes are marked with change bars       **
  46.          
  47. Introduction
  48.  
  49.    OIC is a state-of-the-art object-oriented programming environment for
  50.    the C programming language implemented as a portable library of 
  51.    management routines and a set of programming conventions.  It
  52.    features the following :
  53.    
  54.          Ñ      A fully dynamic class structure
  55.          Ñ      Multiple inheritence
  56.          Ñ      Class variables & class methods
  57.          Ñ      Generic function method dispatch with method caching
  58.          Ñ    True run-time polymorphism
  59.          Ñ      Support for multi-methods
  60.          Ñ      No need for a special pre-processor - will work with ANY C
  61.          Ñ      High speed access to instance variables via C structures
  62.          Ñ      Method dispatch tracing system
  63.          Ñ      Smooth & arbitrary transition between C & OOP code
  64.          
  65.        OIC has more of the flavor of the dynamic, Lisp-based OOPS &
  66.        SmallTalk than of the static languages like C++ and Object Pascal.
  67.        Some of the features, like generic functions, are reasonably
  68.        avant-garde, and are described in the following sections.
  69.        
  70.        There is one major departure from the semantics of these OOP systems
  71.        as a consequence of using no pre-processor & deciding to access
  72.        instance variables via C structures: instance variables effectively 
  73.        have a SINGLE level of scoping.  See the section on Limitations, below
  74.        for a full discussion.
  75.        
  76.        This document assumes a detailed familiarity with C and a reasonable
  77.        understanding of object-oriented programming techniques.  For those 
  78.        without the latter, try "Object-Oriented Programming for the 
  79.        Macintosh" by Kurt Schmucker or "Object-Oriented Programming in
  80.        Common Lisp" by Sonya Keene. The following sections describe the
  81.        implementation approach & memory structures, OIC limitations and
  82.        the example file set.  At the end is a reference list of library
  83.        functions & macros, some warnings about portability limitations,
  84.        and details of the shareware licence. 
  85.                 
  86.                             ------------------
  87.  
  88. Implementation 
  89.  
  90.     This section describes the 3 prime elements of the OIC
  91.     system :
  92.     
  93.         Ñ    object layout, management and access
  94.         Ñ    class layout, management and access
  95.         Ñ    generic function & method creation and dispatch
  96.         
  97.     All 3 involve structures created & managed at run-time by the OIC
  98.     library.  In this version, ALL the structures are allocated as 
  99.     handles, locked & then dereferenced.  This is NOT good form, but
  100.     seems to be the quickest memory management scheme on the Mac.  If
  101.     it offends you, the storage allocation routines in "memory.c" can
  102.     be changed to suit.  The decision to use pointers & not handles
  103.     was to promote portability to C environments other than on the
  104.     Macintosh; a future version may use handles.
  105.     
  106.     Objects
  107.     
  108.         Objects are layed-out in memory as a class tag followed by
  109.         the concatenation of all the instance variables (IVs) defined
  110.         in the object's component classes - i.e., its class and all
  111.         its superclasses, and all their super classes, etc.  Each
  112.         object is allocated as a single block of memory and the IVs 
  113.         are zero-filled.  The class tag defines the object's class
  114.         and is actually a pointer to the class's defining structure
  115.         (described below).  The IV's defined by each component class
  116.         are mapped & accessed by ordinary C structures - when a method
  117.         is invoked, a pointer is supplied that points to the local
  118.         IV structure, i.e., the IVs defined in the class in which the
  119.         invoked method was found.
  120.         
  121.         Objects are always referred to by pointers.  The provided
  122.         "object" typedef declares a pointer storage type that will
  123.         hold a pointer to ANY class of object - the system is
  124.         dynamically polymorhpic.  IVs can be any C type including,
  125.         of course, object.
  126.         
  127.         Objects are created with the "New" function.  It takes a
  128.         class & any number of following arguments.  When created,
  129.         the object has its "new" generic function invoked which
  130.         is passed the other, presumably initialization, arguments.
  131.         
  132.         It is the programmers responsibilty to explicitly free
  133.         memory occupied by unused objects.  The generic function
  134.         "dispose", a method for which is provided in default by
  135.         the root class "Object", will free the originally
  136.         allocated object.  This should be specialised
  137.         if any other housekeeping is needed.  By convention, 
  138.         the generic "deepDispose" will free the object and, 
  139.         recursively, any contained objects.  This, for example,
  140.         is how the supplied List class lists are freed in one go.
  141.                 
  142.                             ------------------
  143.  
  144.     Classes
  145.     
  146.         OIC provides full multiple inheritence of methods.  This is
  147.         supported by a run-time collection of "Class" objects (yes,
  148.         classes are proper objects) arranged in directed, acyclic
  149.         graph.  This D.A.G. maps the inheritence relationships
  150.         among the classes.  All classes inherit eventually from
  151.         the root class "Object" which provides a bunch of useful
  152.         default methods. (see "object.c" for its definition).
  153.         
  154.         Each object is tagged by a pointer to its class's object.
  155.         This is how OIC determines an object's class and contrives
  156.         to dispatch the correct method for a given generic function
  157.         invokation.  Each class object contains instance allocation 
  158.         and IV mapping information, an immediate superclass list,
  159.         the class variables and method invokation information.
  160.         Clearly, a class must exist before any instances of it
  161.         can be created.
  162.         
  163.         The general intention is that each class be defined in a 
  164.         separate source file (see examples) to promote information
  165.         hiding, functional independance & all those good things.
  166.         Each file contains the IV & CV structure definitions, a global 
  167.         to hold the class object, the methods which are written as
  168.         static functions, and an initializing function that creates
  169.         the class and associates its methods with their generic
  170.         functions (see below).
  171.         
  172.         A class is created by the "NewClass" function.  It takes as
  173.         arguments, the size of the IV & CV structures, a class name
  174.         (as a C string) and a null-terminated list of superclasses. 
  175.         The order of this list determines the inheritence priority.
  176.         The supplied method finder does a breadth-first search up
  177.         the superclass tree, scanning across the superclass lists
  178.         at each level in the order in which they were specified to
  179.         the NewClass function. Clearly also, "super"classes
  180.         must exist before they can be specialized or mixed-in.
  181.         
  182.         OIC supports class variables and class methods - see the 
  183.         "IndexMixin" class for an example of how they work.
  184.                 
  185.                             ------------------
  186.  
  187.     Generic Functions and Methods
  188.     
  189.         OIC uses the Generic Function (GF) technique of method dispatch,
  190.         prefered in the current state-of-the-art LISP object-oriented
  191.         systems like CLOS, New Flavors, Common Loops, and Object LISP.
  192.         It has several semantic & performance advantages over the
  193.         message passing schemes and embeds exceptionally cleanly in
  194.         functional languages (like C).
  195.         
  196.         Instead of sending a message identifier to an object as in 
  197.         SmallTalk, or qualifying a function name by a class name as in
  198.         Object Pascal, the generic function is a single function
  199.         defined over a number of argument classes.  It acts like
  200.         a dispatcher which invokes the appropriate method (or methods)
  201.         depending on the class of one (or more) of its arguments and
  202.         hence is "generic".  In the terminology a "generic function"
  203.         embodies many operations depending on the class of its
  204.         arguments.  The different operations are defined by "method
  205.         functions", one in each of the classes that will directly
  206.         handle that generic.
  207.         
  208.         For example, in a messaging-passing system we might have :
  209.         
  210.                     send("append", list, item);
  211.                     
  212.         In a GF system this becomes :
  213.         
  214.                     append(list, item);
  215.                     
  216.         "append" being a function which dispatches to one of the
  217.         various appending methods depending on the class of its first
  218.         argument. This is clearly the preferred form for embedding
  219.         in C. Apart from looking good, a number of neat things follow
  220.         from this technique.
  221.         
  222.         Firstly, it is very simple to write high-speed, caching 
  223.         method dispatchers, usually requiring only a single indexing
  224.         operation to get the method required.
  225.         
  226.         Secondly, individual generic functions can be made to have
  227.         their own dispatching semantics by allowing programmers to
  228.         straight-forwardly define their own dispatching functions.
  229.         
  230.         For example, generic functions can be cleanly made to be driven
  231.         by the classes of several arguments, not just one, allowing
  232.         the implementation of so-called multi-methods.  In a
  233.         mixed-mode arithmetic system, we might have something like :
  234.         
  235.                     add(a, b);
  236.                     
  237.         where a & b have different classes & hence some coercion is
  238.         required.  A dispatching function for a set of math generic
  239.         functions might look at the classes of the arguments, decide
  240.         on the mutually widest class, invoke coercion generics on 
  241.         a & b to that wider class & invoke the add generic on the
  242.         coercions :
  243.         
  244.                     add(coerce(a, wide), coerce(b, wide));
  245.                     
  246.         Another example might be a dispatching function that will handle
  247.         before, after & around daemon methods in the way of ZetaLisp's Flavors.
  248.         
  249.     Defining Generic Functions
  250.     
  251.         OIC comes supplied with only a single kind of generic function;
  252.         one that dispatches on the class of the first argument -
  253.         equivalent to simple message-passing. If inheritence is
  254.         needed it follows a BREADTH-FIRST search up the superclass tree
  255.         caching any found methods for subsequent single-index dispatch.
  256.         
  257.         Generic functions of this simple type are defined using the
  258.         "defGeneric" macro (defined in "object.h").  This macro is
  259.         unfortunately very unwieldly - it requires 3 arguments which
  260.         are just variants of the generic's name (if ONLY one could
  261.         construct symbols & strings in the standard C preprocessor!!!)
  262.         It declares a function with the generic's name having the
  263.         above-mentioned dispatching semantics and declares some tables
  264.         that hold pointers to the method functions.  This method 
  265.         table is used by the dispatching code and is in two parts,
  266.         one for normal methods & the other for class methods; they
  267.         are both indexed by a unique "class index" which is allocated
  268.         when the class is created.
  269.         
  270.         Other kinds of dispatching semantics would be implemented by
  271.         defining and using variants of the defGeneric macro. The
  272.         technique allows multiple concurrent defGeneric variants.
  273.         
  274.     Defining & Invoking Method Functions
  275.     
  276.         As mentioned in the Class section above, the various methods
  277.         for a class are usually defined as static functions in that
  278.         class's source file.  Method functions are passed 3
  279.         arguments on invokation: the dispatching object, a pointer
  280.         to the local IV structure in that object, and a pointer
  281.         to the rest of the arguments given to the generic. For
  282.         example, the generic invokation :
  283.         
  284.                 set(window1, "Untitled", &rect1, VISIBLE);
  285.                 
  286.         would result in calling a method function declared :
  287.         
  288.                 static object
  289.                 set_method(self, ivs, args)
  290.                     object        self;
  291.                     window_iv    *ivs;
  292.                     struct 
  293.                     {
  294.                         char    *title;
  295.                         Rect    *frame;
  296.                         int        visFlag;
  297.                     } *args;
  298.                 {
  299.                     .....
  300.                     ivs->title = args->title;
  301.                     .....
  302.                     set_frame(self, args->frame);
  303.                     .....
  304.                     return self;
  305.                 }
  306.                 
  307.         such that "self" points to the key object "window1",
  308.         "ivs" points to the "window_iv" structure within that
  309.         object (remember all the IV structures of the component
  310.         classes are concatenated to form an object), and "args"
  311.         points to the string, rectangle & visibility arguments.
  312.         
  313.         The "args" argument actually points into the call frame
  314.         of the generic function "set" at its secondary arguments
  315.         on the stack.  This is done for speed & so the dispatcher 
  316.         doesn't have to know how many arguments there are.  This is
  317.         guaranteed to work only in C implementations that use
  318.         the stack for passing arguments (all the C's on the Mac).
  319.         Some C's on large machines with millions of registers use
  320.         them instead of the stack for argument passing and OIC's
  321.         technique wont work (see portability limitations, below).
  322.         
  323.         Also, on those C's that use the stack, structures are
  324.         layed-out in the same way as arguments on the stack,
  325.         so the in-line argument structure declaration is a neat
  326.         way of getting at these "passed-on" arguments.  Remember,
  327.         though, that chars are widened to ints and floats to doubles
  328.         when being placed on the argument stack - they must be
  329.         declared as this widened form in the argument mapping 
  330.         struct.
  331.         
  332.         Note in the example, above, how the IVs & arguments are
  333.         accessed in clean, high-speed ways.
  334.         
  335.     Associating Methods with Generic Functions
  336.     
  337.         A generic function is implemented by a bunch of method
  338.         functions, one from each of the classes that is so 
  339.         inclined.  The association of a method with its generic
  340.         is usually done in the class source file, in the initializing
  341.         function that creates the class (see the example classes).
  342.         
  343.         The function "AddMethod" performs this task and is tuned
  344.         to take a bunch of methods defined in one class & associate them
  345.         one-by-one with each's particular generic.  It takes a class object
  346.         as its first argument followed by a null terminated list of
  347.         pairs: the generic's method table (declared by "defGeneric") and
  348.         the method function, e.g.
  349.         
  350.             AddMethods(List, appendGeneric, appendMethod,
  351.                              headGeneric,   headMethod,
  352.                              tailGeneric,   tailMethod,
  353.                              ....,
  354.                              NULL);
  355.                             
  356.         AddMethods can be called any time and any number of times after
  357.         a class has been created to incrementally add its methods. An
  358.         equivalently argumented function called "AddClassMethods" will
  359.         add class methods to the generics specified. (see IndexMixin.c
  360.         for an example).
  361.                 
  362.                             ------------------
  363.  
  364.     Limitations
  365.     
  366.            Embedding such a system in standard C necessarily involes trade-
  367.            offs.  Some of these have resulted in limitations and others
  368.            in the need for rather cryptic code.
  369.            
  370.            Scope and Inheritence of Instance Variables
  371.            
  372.             The decision to map object instance variables by C 
  373.                structures results in the only major departure from
  374.                conventional OOPS semantics - the SCOPE of instance 
  375.                variables is effectively limited to the level in the class
  376.                hierarchy that defines them.  This single level of
  377.                scoping immediately implies that ALL instance & class 
  378.                variables are inherited; there is no "hiding" of similarly-
  379.                named instance variables up the inheritance chain
  380.                as occurs in some other OOP systems.
  381.             
  382.             Some would contend that this is due & proper adherence
  383.             to the programming principles of encapsulation and,
  384.             fortunately, it rarely causes problems - one tends to be
  385.             interested in the goings-on of the IVs in the 
  386.             methods of the class that defined the IVs. However,
  387.             on some occasions, especially when slightly specialising
  388.             an existing class, it is handy to be able to get at the 
  389.             IVs for that class, and there are 2 ways to achieve this.
  390.             
  391.             The first is to use one of the macros "localIVs" or "myIVs".
  392.             The first allows you to reach into any object of the same
  393.             class as "self" and get at the IV structure for the current
  394.             method's class.  "myIVs" reaches into "self" and gets the
  395.             IVs for any one of its superclasses. See Macros, below for
  396.             further details.
  397.             
  398.             The second way is to provide methods to access IVs.  Most
  399.             of the Lisp OOPS do it this way always, the OOPS system 
  400.             automatically generating the accessing methods - very easy
  401.             to do in Lisp; not so in C.  This technique can, of course,
  402.             be used on an IV-by-IV basis: provide access methods for
  403.             only those that will need to be accessed by specializing
  404.             classes.  Because inherited methods have a nested scoping - 
  405.             closer ones hide ones farther up the inheritence chain - this
  406.             technique also provides a way of implementing nested 
  407.             inheritence of selected IVs.
  408.             
  409.                                 ------------------
  410.  
  411.        Source File Structure & Coding Conventions
  412.        
  413.            In the example classes and according to the recommended way of
  414.            using OIC there is one source file for each class.  This
  415.            yields a convenient modularity and allows the desired
  416.            kinds of information hiding to be set up.  Each class
  417.            source file usually contains :
  418.            
  419.                1.    The IV & (possibly) CV structure definitions.
  420.                     They will need to be moved out into an include
  421.                     file if several classes (which should always
  422.                    be inheriting classes) are to get at them.
  423.                    
  424.                2.    A class global to hold the class object.
  425.                
  426.                3.    The methods defined in this class, usually
  427.                    as static functions.  Note in the example
  428.                    classes that these are named with the 
  429.                    generic name prefixed by an underscore; you
  430.                    might be happier with the generic name post-
  431.                    fixed with "Method" or whatever; in any event,
  432.                    they must be different from the actual generic
  433.                    function's name.
  434.                    
  435.                4.    Any local utility functions that the above might use.  
  436.            
  437.                5.    An initializing function that creates the class
  438.                    and associates its methods with their corresponding
  439.                    generics.  This function needs to be called during
  440.                     initialization in the main code.
  441.            
  442.            The declaring of generic functions requires some care.  They
  443.            are intended to be program-wide globals and are probably best
  444.            all declared in one spot because almost any class might 
  445.            wind up defining a method for one.  In the example file set
  446.            they are all declared in "generics.c".  They also need to be
  447.            declared external in all the source files that might use
  448.            them; in the example kit this is done in the include file
  449.            "generics.h".
  450.            
  451.            Any file that uses OIC should include "oic.h" - it defines
  452.            all the OIC typedefs, macros & externals.
  453.                 
  454.                             ------------------
  455.  
  456.     Example File Set
  457.     
  458.         This explorer's kit is intended primarily to place a working
  459.         object-oriented C programming mechanism into the hands of 
  460.         expert C programmers for their edification, enjoyment and,
  461.         hopefully, serious use.  The demo classes and small test
  462.         main program are not intended to be a tutorial on OOPS
  463.         programming, nor to necessarily form the basis for a serious
  464.         suite of classes.  They are simply the test classes I built
  465.         as OIC came together, suffer somewhat from its growing
  466.         pains, and are provided to help illuminate the basic
  467.         object manager.
  468.         
  469.         The base object manager is represented in the files :
  470.         
  471.             oic.c          - the basic management routines
  472.             memory.c    - customizable object allocation routines
  473.             oic.h           - the include file for anybody using oic
  474.             Object.c    - the root class
  475.             Class.c        - the class class
  476.             
  477.         Certain of the class files go to make up the so-called
  478.         system classes :
  479.         
  480.             List.c         - a general purpose list class
  481.             String.c     - a class to hold C strings
  482.             Replist.c     - a representation class for nested objects
  483.             Collect.c     - a generic superclass that adds lots of
  484.                            neat collection methods to any class that
  485.                            provides head, tail, push & eq
  486.             List2.c         - a version of the list class using Collect
  487.             IndexMixin.c - a mixin (a modifying superclass) that will
  488.                            keep track of all the instances of a class
  489.                            that uses it as a superclass
  490.             Linkseq.c     - a general purpose sequencing class for
  491.                            classes that understand head, tail & isEmpty]
  492. |            DependentsMixin.c - a mixin that keeps a dependents list for
  493. |                           its inheritors.
  494. |            StdioStream.c - provides text I/O
  495. |            Name.c         - a specialization of string for storing names
  496. |            Binding.c     - binds a key object to a value object. 
  497. |            HashTable.c     - maintains a hashed table of bindings - a 
  498. |                           lookup table.
  499. |            NameSpace.c     - a specialization of HashTable that provides
  500. |                           a nested scoping.  It is intended that Names be
  501. |                           used as keys.
  502. |            NameMixin.c     - makes instances of inheriting classes nameable
  503. |                           in a global object name space.
  504. |            NameTable.c     - a degenerate form of lookup table that uses
  505. |                            == comparisons (i.e. good for Names) no hashes.
  506. |                           For fast, small lookup tables.
  507.             generics.c   - defGenerics for all the above classes
  508.             generics.h     - external definitions for the above classes
  509. |            names.h         - external definitions for the NameSpace classes
  510.         
  511.         Notes:
  512.         
  513.         1. The List class does NOT implement standard LISP lists, the
  514.            operations all destructively modify the subject list. It
  515.            will only hold OIC objects as elements.
  516.            
  517.         2. The IndexMixin class provides an example of how to use
  518.            class variables & class methods.  It specializes the "new"
  519.            method & maintains a list (using the List class) of each
  520.            instance of a class inheriting from it in a class variable.
  521.            They can be got by invoking "allInstances" on the class you
  522.            are keeping track of. It also adds a "sequence" class method
  523.            so you can simply sequence over the class.  It is an 
  524.            example of a so-called "mixin" class, not intended to be
  525.            used on its own but "mixed-in" with some base class usually
  526.            providing some extra behaviour.  This kind of class is
  527.            only possible in a multiple inheritance system.
  528.            
  529.         3. The Replist class is a specialization of the List class
  530.            intended to help formatting & printing nested objects
  531.            like Lists.  It gets used by the repList methods in various
  532.            classes to create a structure isomorphic to the object
  533.            being printed but with String representations of the
  534.            object's leaf values instead of the values themselves.
  535.            This can then be neatly parenthesised & indented, etc. See
  536.            how it gets used by looking at the print method in the
  537.            root Object class (object.c).  This print method is
  538.            inherited by EVERY class and so provides a simple
  539.            object printer for any class that can generate a Replist
  540.            of itself (see List).
  541.            
  542.         4. the Linkseq class is an example of what could be
  543.            a suite of sequencing utility classes.  Its purpose is
  544.            to wrap up an object that is being sequenced over to
  545.            provide the sequencing context.  Note how it gets used
  546.            in the test program, main.c.  There are several
  547.            "for" statements that invoke the "sequence" generic on
  548.            an object.  Any object that is sequencable should 
  549.            define a sequence method that will wrap itself up
  550.            in, and return, one of these utility sequence classes.
  551.            This class should, in turn, respond to the generics
  552.            "start", "next", "moreInSeq", & "restart".  Other
  553.            kinds of sequence "wrapper" classes might work for
  554.            scalars by generating consecutive values, strings by
  555.            sequencing through the characters, or arrays by indexing
  556.            through their elements.  See how neatly (in main.c) we get
  557.            general purpose polymorphic sequencing in an ordinary
  558.            old C "for" statement. 
  559.         
  560. |        5. The Name class brings a measure of efficiency to the use
  561. |           of Strings as names (in symbol tables, etc).  Instances 
  562. |           made with the class method "declare" form a proper set,
  563. |           i.e. the string is stored only once and the same string 
  564. |           yields identically the same object.  This allows == 
  565. |           comparisons on object pointers for name equality and
  566. |           saves space at the same time!  In other words, dont use
  567. |           the "New" primitive to create instances, use the class
  568. |           method "declare".
  569. |
  570. |           The HashTable, Binding & NameSpace classes cooperate
  571. |           to provide a nestable, hashed run-time symbol table 
  572. |           capability.  They will be used by the Lisp class kit.
  573.  
  574.         A small test program with some other little classes is 
  575.         contained in the files :
  576.         
  577.             main.c        - the main test procedure
  578.             Coord.c        - a kind of point class
  579.             Box.c        - a kind of rectangle class
  580.             TestWindow.c - a trivial window class that experiments
  581.                           with keyword arguments!
  582.                 
  583.                             ------------------
  584.  
  585.        OIC System Typedefs
  586.        
  587.         typedef struct class *class            - declares a holder for a class object
  588.         typedef struct class **object        - declares a holder for an object
  589. |        typedef GenericTable *generic        - declares a generic definition table
  590. |                                              pointer
  591.         
  592.        OIC System Functions
  593.        
  594.         class  NewClass(iv_size, cv_size, name, super1, super2, ... NULL)
  595.                     int     iv_size;
  596.                     int     cv_size;
  597.                     char     *name;
  598.                     class    super1, super2, ...;
  599.                     
  600.                     creates a new class with local IV & CV structure sizes as given
  601.                     and that inherits from the null-terminated list of superclasses.
  602.                     The order of this list determines the inheritence priority.
  603.                     The supplied method finder does a breadth-first search up
  604.                     the superclass tree, scanning across the superclass lists
  605.                     at each level in the order in which they were specified to
  606.                     the NewClass function.
  607.                     The class name is used for debugging & tracing output.
  608.                 
  609.         object New(class, initializing arguments ...)
  610.                     class    class
  611.                     <any>    initializing arguments ...;
  612.                     
  613.                     creates a new object of the given class. Invokes the "new"
  614.                     generic on the fresh object, passing it the initialization
  615.                     arguments.
  616.         
  617.         void   AddMethods(class, generic1, method1, generic2, method2, ..., NULL)
  618.                     class        class;
  619.                     MethodTable    generic1, generic2, ...;
  620.                     <any>        (*method1)(), (*method2)() ...;
  621.                     
  622.                     associates methods for the given class with their generic
  623.                     functions.  The generics are specified by passing the method
  624.                     table that is created by the "defGeneric" macro (see below).
  625.                     
  626.         
  627.         void   AddClassMethods(class, generic1, method1, generic2, method2, ..., NULL)
  628.                     class        class;
  629.                     MethodTable    *generic1, *generic2, ...;
  630.                     <any>        (*method1)(), (*method2)() ...;
  631.                     
  632.                     associates class methods for the given class with their generic
  633.                     functions.  The generics are specified by passing the method
  634.                     table that is created by the "defGeneric" macro (see below).
  635.                     
  636.         object Super(object, arguments...)
  637.                     object    object;
  638.                     <any>    arguments;
  639.                     
  640.                     invokes the method for the currently executing generic that is
  641.                     next higher up the inheritance path than the current method. This
  642.                     is very useful when one wishes merely to augment the operation
  643.                     of an inherited method, rather than completely replace it.
  644.  
  645. |        object SuperFrom(class, object, arguments...)
  646. |                    class    class;
  647. |                    object    object;
  648. |                    <any>    arguments;
  649. |                    
  650. |                    same as "Super" but the 'class' argument specifies exactly from
  651. |                    which ancestor class to inherit the method.  Very useful when
  652. |                    using mixin classes to make sure they get a look at "new"s and
  653. |                    "dispose"s, for example.
  654. |                    
  655. |                    All inheritors of DependentsMixin, for example, must use :
  656. |                    
  657. |                            SuperFrom(DependentsMixin, self);
  658. |                            
  659. |                    in there "dispose" methods to make sure it disposes the dependents
  660. |                    list.
  661.                     
  662.         object SuperPassArgs(object, argumentListPtr)
  663.                     object    object;
  664.                     <any>    *argumentListPtr;
  665.                     
  666.                     same as "Super" but a pointer to the argument list is given
  667.                     rather than specifying them in place.  This is useful for passing
  668.                     the argument list pointer that a method normally gets straight
  669.                     through to the super method.
  670.                     
  671. |        object ApplyGeneric(gen, obj, args)
  672. |                    generic        gen;
  673. |                    object        obj;
  674. |                    <any>        *args;
  675. |                    
  676. |                    given a generic table reference, dispatches the appropriate
  677. |                    method on the given object.  Takes a pointer to an argument
  678. |                    list.  (not the args, themselves).  Often used to 'pass on'
  679. |                    arguments to another generic:
  680. |                    
  681. |                            ApplyGeneric(drawGeneric, self, ap);
  682.                     
  683.         int    SizeOf(object)
  684.                     object    object;
  685.                     
  686.                     returns the total size of the object in bytes.
  687.                     
  688.         char   *ClassNameOf(object)
  689.                     object    object;
  690.                     
  691.                     returns the class name of the object as a C string.
  692.                     
  693.         char   *MethodName(generic)
  694.                     MethodTable    *generic;
  695.         
  696.                     returns the name of a generic as a C string given the generics
  697.                     method table (as defined by "defGeneric", see below).
  698.                     
  699.         int    IsA(object, class)
  700.                     object    object;
  701.                     class    class;
  702.                     
  703.                     returns true if the object is of the given class.
  704.                                         
  705.         int    IsAKindOf(object, class)
  706.                     object    object;
  707.                     class    class;
  708.                     
  709.                     returns true if the object is of the given class or inherits from
  710.                     that class.
  711.                                         
  712.         int       IsObj(object)
  713.                     object    object;
  714.                     
  715.                     attempts to check whether object is a valid object. It does 
  716.                     this by ensuring that "object" is a valid pointer, points into
  717.                     the application heap, points at a tag that points at a class
  718.                     which itself has a tag which must point to the "Class" object.
  719.                     It can be fooled, so beware.
  720.                     
  721.         void   InitOIC()
  722.         
  723.                     creates & initializes the OIC system.  Should be called
  724.                     EXACTLY once before any of the OIC functionality is used.
  725.         
  726.         void   InitSysClasses()
  727.         
  728.                     creates & initializes the system classes.
  729.         
  730.         void    TraceOn()                - turns on generic call tracing
  731.         void    TraceOff()                - turns it off
  732.         void    TraceObj(object)        - traces any generics called on object
  733.         void    TraceClass(class)        - traces any generics ony any "class" object
  734.         void    dumpClass(class)        - debugging class dump
  735.         void    dumpMethodTable(mth)    - debugging method table dump
  736.  
  737.     OIC System Globals
  738.  
  739.         class currentClass;        - the class in which the currently executing
  740.                                   method was found.
  741.         class classes;            - a linked list of all classes created. You can 
  742.                                   get a List of the classes by invoking subs(Object);
  743.         class Class;            - the class class.
  744.         class Object;            - the root object class. ALL classes inherit 
  745.                                   eventually from Object
  746. |        generic    generics;        - linked list of generic definition tables
  747. |        object namedObjects;    - the NameSpace of named objects (kept by NameMixin)
  748.  
  749.     Object methods
  750.     
  751.         The following methods are provided as defaults by the root class Object.
  752.         ALL classes, therefore, support these methods by default inheritence.
  753.                                   
  754. |        equal(obj1, obj2)        - a byte wise comparison of the contents of each 
  755.         new(obj, args...)        - dummy "new" method
  756.         className(obj)            - class name as a String object
  757.         print(obj)                - invokes print(repList(obj))
  758.         repList(obj)            - default object representation. creates a
  759.                                   replist by stepping through obj
  760.                                   sizeof(object) (4 bytes) at a time. If
  761.                                   the current 4 bytes is a valid object
  762.                                   reference recursively calls repList,
  763.                                   otherwise adds a hex representation to
  764.                                   the repList
  765. |        map(obj, f, args....)    - maps the function "f" over each item in "obj"
  766. |                                  by using "sequence" on "obj".
  767. |        forAll(obj, f, args...)    - identical to "map".
  768. |        forAllGen(obj, gen, argp) - takes a generic table reference & applies
  769. |                                  its generic over the "sequence" of "obj".
  770. |        cantDo(obj, gen, argp)  - invoked if "obj" can't do generic "gen".  Prints
  771. |                                  an error message.  This should be specialized by
  772. |                                  classes that want to handle this their own way.
  773. |        dispose(obj)            - frees the memory occupied by "obj".  Invalidates
  774. |                                  the class tag to make it fail any future uses.
  775.         
  776.     Class methods
  777.     
  778.         supers(class)            - returns a (List) list of all the classes ancestors
  779.         subs(class)                - returns a (List) list of all the classes that 
  780.                                   inherit from "class"
  781.         print(class)            - prints the class name
  782.         repList(class)            - returns the class name as replist
  783.  
  784.         
  785.     OIC System Macros & Defines
  786.  
  787.         defGeneric(generic, methodTable, name)
  788.         
  789.                 declares a generic function and its attendant method table.
  790.                 This macro must be called once for each unique generic
  791.                 function in the system - generics are global functions.
  792.                 The macro is given the generic's name, the name to be used
  793.                 for the generic's method table, and the generic's name as
  794.                 a C string constant.
  795.                 
  796.                 If C's preprocessor were even the tiniest bit smart it would
  797.                 allow one to create symbols & strings & you have only had to
  798.                 give defGeneric one argument. Ah, well.
  799.                 
  800.                 For example :
  801.                 
  802.                         defGeneric(print, printGeneric, "print");
  803.                     
  804.         externGeneric(generic, methodTable)
  805.         
  806.                 declares an external reference to a generic function. 
  807.                 Usually both the generic function itself and its
  808.                 method table need to be accessible, and this macro
  809.                 eases their declaration. (see generics.h)
  810.                 
  811.                 For example :
  812.                 
  813.                         externGeneric(print, printGeneric);
  814.  
  815.         localIVs(obj, structure)
  816.         
  817.                 computes a pointer to the IV structure in "obj" for
  818.                 to the current class. This is useful if I'm working
  819.                 with two objects of the same class (say, Lists that
  820.                 I'm concatenating) and I want to reach into the
  821.                 IV's of both of them (see _join in list.c).  The 
  822.                 "structure" argument is just used to cast the 
  823.                 resulting pointer to that which you want (the 
  824.                 structure typedef for the current class's IVs).
  825.                     
  826.         myIVs(class, structure)
  827.         
  828.                 computes a pointer to the IVs of "self" for the
  829.                 given "class".  This is the macro that gets around
  830.                 the one-level scoping problem - I can reach back
  831.                 and get at the IVs of any superclass I want (providing
  832.                 the structure typedefs are available - you may 
  833.                 want to enforce the hiding by keeping these typedefs
  834.                 private).
  835.                     
  836.         localCVs(class, structure)
  837.         
  838.                 as for localIVs but point at the class variables instead.
  839.                     
  840.         myCVs(class, structure)
  841.                     
  842.                 as for myIVs but point at the class variables instead.
  843.         
  844. |        IVs(obj, class, structure)
  845. |        
  846. |                computes a pointer to the IV structure in "obj" from
  847. |                "class".  The "structure" argument is just used to
  848. |                cast the resulting pointer to that which you want (the 
  849. |                structure typedef for the current class's IVs).
  850. |                                    
  851. |        CVs(obj, class, structure)
  852. |        
  853. |                same as IVs but returns a pointer to the "class"es
  854. |                CV structure.
  855.                 
  856.         ClassOf(object)
  857.         
  858.                 computes the class of the given object
  859.                 
  860. |        method
  861. |                
  862. |                just a synonym for "static" to make method function 
  863. |                declarations look more like methods.
  864.  
  865.         CHECK_OBJS
  866.         
  867.                 if defined in "oic.c" will cause all oic functions to
  868.                 check for valid class & object arguments (by using IsObj()).
  869.                 This is a conditional assembly flag and is set on in the
  870.                 distributed kit.
  871.                 
  872. |        IGNORE_NULL_OBJS
  873. |        
  874. |                if defined in "oic.c" causes method dispatch to detect
  875. |                a NULL pointer as the dispatching object and simply 
  876. |                return NULL without complaining.  This is useful if you
  877. |                frequently checking for NULL objects (often in IVs as
  878. |                they are initialized NULL) before invoking generics on them.
  879. |                But, beware, this prevents CHECK_OBJS from detecting 
  880. |                NULL objects which is often a frequent bug in early
  881. |                development.  You will have to choose whether you want the
  882. |                convenience of not having to detetct NULL objects or
  883. |                the safety of error checking. 
  884.                     
  885.         END
  886.         
  887.                 equivalent to NULL. Used sometimes to mark the end
  888.                 of argument lists.  Another gripe: why didnt they
  889.                 design C so you could find out how many arguments you
  890.                 were given - after all, the function call form is
  891.                 completely polymorphic - I can understand the lack in
  892.                 a language with compile-time isomorphism checks like
  893.                 Pascal.
  894.                 
  895.                             ------------------
  896.  
  897.     Portability Considerations
  898.     
  899.         There is really only one major portability consideration and that 
  900.         involves OIC's expectations about the use of the stack for passing
  901.         arguments.  It expects all arguments to be placed on the stack 
  902.         with earlier arguments at lower addresses. 
  903.         On 680x0s and 80x86s there is no other sensible option and so
  904.         OIC should port without trouble on C compilers for those machines
  905.         (the techniques have been tried on 68010 Unix 4.2BSD and 80286
  906.         Xenix & MS-DOS boxes succesfully).
  907.         
  908.         OIC was developed in THINK's Lightspeed C, an extremely good C
  909.         development environment for the Macintosh. It has also run without
  910.         change using Aztec C.  
  911.         
  912.         The current version does make use of UNIX-like standard I/O calls
  913.         for outputing errors and trace messages. Both LSC and Aztec provide
  914.         a Unix emulation library for this. You may have trouble if your C
  915.         doesn't, in which case you should recode all the printf's &
  916.         fprintf's.  Indeed, in the full OIC, this use of Unix emulation
  917.         will go and be replaced by the use of generic, stream-based text
  918.         window classes.
  919.                 
  920.                             ------------------
  921.  
  922. |    Tips on using OIC with the THINK LSC Debugger on the Macintosh
  923. |    
  924. |        There is one problem and a couple of tricks associated with using the
  925. |        THINK C Debugger.  The debugger wont correctly "step" into a generic
  926. |        function invokation.  This is because the source for the generic
  927. |        dispatching code is hidden in a macro expansion and the debugger likes
  928. |        to have actual source to show as it is stepping.  THINK is looking 
  929. |        at this problem but apparently it is hard to fix.  The only thing 
  930. |        to do at the moment is to manually place a break-point in the method 
  931. |        you expect the generic to invoke and "go" to it.
  932. |        
  933. |        Inspecting objects in the data window requires some tricks.  If you just
  934. |        keep derefering an object pointer you will wind up examining it's
  935. |        class structure (which, of course, you may want to do).  If however,
  936. |        you want to see the IV structure then you should use the IV accessing
  937. |        macros; fortunately the data window accepts macros.  So, to see the
  938. |        local IVs of self, use 
  939. |        
  940. |                        localIVs(self, xxxx_i)   /* xxxx is the IV structure typedef */
  941. |                        
  942. |        If you want to look inside an arbitrary object, use 
  943. |        
  944. |                        IVs(obj, class, xxxx_i)
  945. |                        
  946. |        This will display the IV's of "obj" for the given "class".  It will be
  947. |        necessary in this case to have the IV structure declaration available.
  948. |        It is useful, during debugging, to have one header file containing all
  949. |        the IV structure declarations temporarily included in each file for this
  950. |        purpose.
  951.                 
  952.                             ------------------
  953.  
  954.     Licensing Terms
  955.     
  956.         This software is distributed as shareware; if you wind up using it
  957.         for developing any software, particularly commercial software, please
  958.         send the $20 fee to the address below.  You will become a registered
  959.         user and have access to upgrades & class kits as they become
  960.         available.
  961.         
  962.         The software is also distributed AS IS, with no warranty, expressed or
  963.         implied, of the correctness or suitability of this software for any purpose.
  964.         No responsibility is assumed for damages arising from the use of this 
  965.         software.
  966.         
  967.         OIC is protected by copyright and all commercial rights are reserved.
  968.         Under NO circumstances may this software be distributed in any decodable
  969.         source form, or any form that might be usable as a programming tool
  970.         for commercial advantage.  Reasonable duplication costs can be charged.
  971.         
  972.         Under the shareware ethic, however, you are free to copy & distribute
  973.         the OIC software UNCHANGED, providing this document & licensing terms
  974.         are also copied & distributed with the OIC software.
  975.         
  976.         Feedback & queries are welcome.  I am interested in any classes that
  977.         you may develop - indeed, it seems to me that the success
  978.         of a system like this will primarily be a function of the quantity and
  979.         quality of classes available.
  980.         
  981.             
  982.         Have fun!
  983.             
  984.                         John Wainwright
  985.                         454 West 20th Street, #2
  986.                         New York, NY  10011
  987.                         
  988.                         Compuserve : 72657,2534
  989.         
  990.         
  991.         All OIC files & documentation are Copyright ⌐ John Wainwright, 1988, 1989